package com.seeyon.apps.lzmzj.kit;

import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.util.JDBCAgent;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <pre>
 * 直接操作数据库的类
 * </pre>
 */
public class DBKit {

    /**
     * 执行SQL语句并返回结果列表
     * 该方法用于执行数据库查询操作，支持带有参数的SQL语句
     *
     * @param sql SQL语句，可以是带占位符的查询语句
     * @param params SQL语句的参数列表，如果SQL语句没有参数，则传入null
     * @return 包含查询结果的列表，每个查询结果是一个键值对映射，键是列名，值是对应的数据
     * @throws Exception 如果执行SQL语句时发生错误，则抛出异常
     */
    public static List<Map<String, Object>> excuteSQL(String sql, List<Object> params) throws Exception {
        // 初始化一个空的列表，用于存储查询结果
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        // 创建JDBCAgent实例，开启数据库连接
        JDBCAgent jdbc = new JDBCAgent(true);
        try {
            // 判断参数列表是否为空，如果为空，则执行不带参数的SQL语句
            if (null == params) {
                jdbc.execute(sql);
            } else {
                // 否则，执行带参数的SQL语句
                jdbc.execute(sql, params);
            }
            // 判断SQL语句是否以"update"开头，如果不是，则将查询结果转换为列表
            if (!sql.startsWith("update")) {
                list = jdbc.resultSetToList();
            }
        } catch (Exception e) {
            // 打印异常信息，并重新抛出异常
            e.printStackTrace();
            throw e;
        } finally {
            // 关闭数据库连接
            jdbc.close();
        }
        // 返回查询结果列表
        return list;
    }

    /**
     * 执行更新或删除数据库的操作
     *
     * @param sql SQL语句，用于指定要执行的更新或删除操作
     * @return 受操作影响的行数
     * @throws BusinessException 如果执行SQL过程中发生错误，则抛出业务异常
     */
    public static int updateOrDelData(String sql) throws BusinessException {
        // 创建JDBCAgent实例，设置自动提交为true以适应更新或删除操作
        JDBCAgent jdbc = new JDBCAgent(true);
        int num = 0;
        try {
            // 执行SQL语句并返回影响的行数
            num = jdbc.execute(sql);
        } catch (SQLException e) {
            // 捕获SQL异常并打印错误信息，不抛出新的异常以保持方法签名的简洁性
            e.printStackTrace();
        } finally {
            // 释放数据库资源，确保在操作结束后关闭JDBCAgent实例
            jdbc.close();
        }
        // 返回影响的行数，作为操作结果
        return num;
    }

    /**
     * 执行批量更新操作
     * 该方法用于执行数据库的批量更新操作，如插入、更新或删除多条记录
     * 它通过JDBCAgent对象来准备SQL语句并执行批量更新
     *
     * @param sql SQL语句，用于指定批量更新的操作
     * @return 返回受影响的记录数
     * @throws BusinessException 当执行批量更新过程中发生异常时抛出
     */
    public static int updateBatch(String sql) throws BusinessException {
        // 创建JDBCAgent对象，用于数据库操作，并开启批处理模式
        JDBCAgent agent = new JDBCAgent(true);
        try {
            // 准备SQL语句，以便进行批量更新
            agent.batch1Prepare(sql);
            // 执行批量更新，并返回受影响的记录数
            return agent.batch3Execute();
        } catch (Exception e) {
            // 捕获异常，并抛出自定义的BusinessException
            throw new BusinessException(e);
        } finally {
            // 释放资源，确保数据库连接被关闭
            agent.close();
        }
    }

    /**
     * 执行SQL语句创建数据库表
     *
     * @param sql SQL建表语句，用于在数据库中创建新表
     * @return 返回执行SQL语句影响的行数
     * @throws BusinessException 当数据库操作失败时抛出业务异常
     */
    public static int createTable(String sql) throws BusinessException {
        // 初始化JDBCAgent对象，用于数据库连接和操作
        JDBCAgent jdbc = new JDBCAgent(true);
        int num = 0;
        try {
            // 执行SQL语句，创建表，并返回影响的行数
            num = jdbc.execute(sql);
        } catch (SQLException e) {
            // 打印SQL异常信息，便于问题追踪和调试
            e.printStackTrace();
        } finally {
            // 关闭数据库连接，释放资源，避免内存泄漏
            jdbc.close();
        }
        // 返回执行SQL语句影响的行数
        return num;
    }


}
